package com.star.markdown;

import javax.swing.*;
import javax.swing.filechooser.FileFilter;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;

public class AppView {

    private final JLabel labelChoiseFileName, labelNotice;
    private final JButton buttonSingleFile, buttonMutilFile;
    private String currentPath;

    public static void main(String[] args) {
        new AppView();
    }

    public AppView() {
        String appName = "MD转换器";

        JFrame jf = new JFrame(appName);
        jf.setLayout(new GridLayout(5, 1));

        JLabel title = new JLabel("点击按钮选这Markdown文件", JLabel.CENTER);
        title.setFont(new Font("宋体", Font.BOLD, 16));
        jf.add(title);

        buttonSingleFile = new JButton("选择一个Markdown文件");
        buttonSingleFile.setPreferredSize(new Dimension(200, 30));
        buttonSingleFile.setFont(new Font("宋体", Font.PLAIN, 16));
        buttonSingleFile.addActionListener(new ButtonSingleFileActionListener());

        buttonMutilFile = new JButton("选择一个文件夹");
        buttonMutilFile.setPreferredSize(new Dimension(200, 30));
        buttonMutilFile.setFont(new Font("宋体", Font.PLAIN, 16));
        buttonMutilFile.addActionListener(new ButtonMutilFileActionListener());

        JPanel panel = new JPanel();
        panel.add(buttonSingleFile, BorderLayout.CENTER);
        panel.add(buttonMutilFile, BorderLayout.CENTER);
        jf.add(panel);

        labelChoiseFileName = new JLabel("", JLabel.CENTER);
        labelChoiseFileName.setFont(new Font("宋体", Font.PLAIN, 16));
        jf.add(labelChoiseFileName);

        labelNotice = new JLabel("", JLabel.CENTER);
        labelNotice.setFont(new Font("宋体", Font.PLAIN, 16));
        jf.add(labelNotice);

        //设置窗体大小 600*800 并居中
        int screenWidth = Toolkit.getDefaultToolkit().getScreenSize().width;
        int screenHeight = Toolkit.getDefaultToolkit().getScreenSize().height;
        int jframeWidth = 500;
        int jframeHeight = 260;
        jf.setBounds((screenWidth / 2) - (jframeWidth / 2), (screenHeight / 2) - (jframeHeight / 2), jframeWidth, jframeHeight);
        jf.setVisible(true);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    // 选择一个Markdown文件 事件处理
    class ButtonSingleFileActionListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent arg0) {
            JFileChooser fc = new JFileChooser(currentPath);

            fc.addChoosableFileFilter(new JavaFileFilter("md"));//导入可选择的文件的后缀名类型
            fc.setAcceptAllFileFilterUsed(false);
            fc.setFileSelectionMode(JFileChooser.FILES_ONLY); // 只选文件

            int val = fc.showOpenDialog(null);    //文件打开对话框
            if (val == JFileChooser.APPROVE_OPTION) {
                //正常选择文件
                String markdownPath = fc.getSelectedFile().getAbsolutePath();
                currentPath = Paths.get(markdownPath).getParent().toString();

                labelChoiseFileName.setText("选择的文件：" + fc.getSelectedFile().getName());
                // 生成文件

                labelNotice.setText("正在生成文件");
                String htmlPath = markdownPath.replace(".md", ".html");
                new Thread(() -> {
                    try {
                        MarkdownUtils.toHtml(markdownPath, htmlPath);
                        labelNotice.setText("HTML文件生成成功");
                    } catch (IOException e) {
                        e.printStackTrace();
                        labelNotice.setText("HTML文件生成失败");
                    }
                }).start();
            } else if (val == JFileChooser.CANCEL_OPTION) {
                // 取消选择
                labelNotice.setText("取消选择");
            } else {
                // 其他情况
                labelNotice.setText("未知异常，请联系作者");
            }
        }
    }

    // 选择一个文件夹 事件处理
    class ButtonMutilFileActionListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent arg0) {
            JFileChooser fc = new JFileChooser(currentPath);

            fc.setAcceptAllFileFilterUsed(false);
            fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); // 只选文件夹

            int val = fc.showOpenDialog(null);    //文件打开对话框
            if (val == JFileChooser.APPROVE_OPTION) {
                //正常选择文件
                String markdownPath = fc.getSelectedFile().getAbsolutePath();
                currentPath = Paths.get(markdownPath).getParent().toString();

                labelChoiseFileName.setText("选择的文件夹：" + fc.getSelectedFile().getAbsolutePath());
                // 生成文件
                try {
                    labelNotice.setText("正在生成文件");
                    buttonSingleFile.setEnabled(false);
                    buttonMutilFile.setEnabled(false);
                    new Thread(() -> {
                        generatorAllFile(markdownPath);
                        labelNotice.setText("HTML文件生成成功");
                        buttonSingleFile.setEnabled(true);
                        buttonMutilFile.setEnabled(true);
                    }).start();
                } catch (Exception e) {
                    e.printStackTrace();
                    labelNotice.setText("HTML文件生成失败");
                }
            } else if (val == JFileChooser.CANCEL_OPTION) {
                // 取消选择
                labelNotice.setText("取消选择");
            } else {
                // 其他情况
                labelNotice.setText("未知异常，请联系作者");
            }
        }

        /**
         * 递归生成文件
         *
         * @param path /
         */
        public void generatorAllFile(String path) {
            Path startDir = Paths.get(path);
            FileVisitor<Path> visitor = new MarkdownFileVisitor();
            try {
                Files.walkFileTree(startDir, visitor);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 目录递归
     */
    class MarkdownFileVisitor extends SimpleFileVisitor<Path> {

        @Override
        public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
            // System.out.format("%s [Directory]%n", dir);
            return FileVisitResult.CONTINUE;
        }

        @Override
        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
            String markdownPath = file.toFile().getAbsolutePath();

            if (markdownPath.endsWith(".md")) {
                String htmlPath = markdownPath.replace(".md", ".html");
                labelNotice.setText("正在生成：" + file.getFileName());
                System.out.format("%s [File,  Size: %s  bytes]%n", file.getFileName(), attrs.size());
                try {
                    MarkdownUtils.toHtml(markdownPath, htmlPath);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return FileVisitResult.CONTINUE;
        }
    }

    /**
     * 文件过滤器
     */
    static class JavaFileFilter extends FileFilter {
        String ext;

        public JavaFileFilter(String ext) {
            this.ext = ext;
        }

        /* 在accept()方法中,当程序所抓到的是一个目录而不是文件时,我们返回true值,表示将此目录显示出来. */
        @Override
        public boolean accept(File file) {
            if (file.isDirectory()) {
                return true;
            }
            String fileName = file.getName();
            int index = fileName.lastIndexOf('.');
            if (index > 0 && index < fileName.length() - 1) {
                // 表示文件名称不为".xxx"现"xxx."之类型
                String extension = fileName.substring(index + 1).toLowerCase();
                // 若所抓到的文件扩展名等于我们所设置要显示的扩展名(即变量ext值),则返回true,表示将此文件显示出来,否则返回
                // true.
                return extension.equals(ext);
            }
            return false;
        }

        // 实现getDescription()方法,返回描述文件的说明字符串!!!
        @Override
        public String getDescription() {
            if ("md".equals(ext)) {
                return "markdown(*.md)";
            }
            return null;
        }
    }

}